package com.lagou.edu.component;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.lagou.edu.filer.TPMonitorFilter;
import com.lagou.edu.model.Stat;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @program: stage-3-module-3
 * @description:
 * @author: zhangxiaoyang
 * @date: 2020-09-02 15:19
 **/
public class TPMonitorThread {

    private static final double ALARM_90_PERCENT = 0.90;
    private static final double ALARM_99_PERCENT = 0.99;


    public TPMonitorThread() {
//        Executors.newScheduledThreadPool(15)
//                 .scheduleAtFixedRate(this, 1, 5, TimeUnit.SECONDS);
        // 每隔5秒打印接口性能数据
//        Executors.newSingleThreadScheduledExecutor()
//                 .scheduleWithFixedDelay(this, 0, 5, TimeUnit.SECONDS);

        ThreadFactory threadFactory = new DefaultThreadFactory("性能监控", true);
        Future<?> future = new ScheduledThreadPoolExecutor(20, threadFactory, (runnable, executor) -> executor.submit(runnable)).scheduleWithFixedDelay(() -> {
            Map<String, LinkedList<Stat>> queueMap = Collections.unmodifiableMap(TPMonitorFilter.PERFORMANCE_MAP);
//            System.out.println(Thread.currentThread()
//                                     .getName() + "请求数据大小:" + queueMap.values()
//                                                                      .stream()
//                                                                      .flatMap(stat -> stat.stream())
//                                                                      .collect(Collectors.toList())
//                                                                      .size() + ">>>>>>>>>>打印接口性能数据" + queueMap);
            for (Map.Entry<String, LinkedList<Stat>> entry : queueMap.entrySet()) {
                LinkedList<Stat> statQueue = entry.getValue();
                List<Long> responseTimeList = Lists.newLinkedList();
                statQueue.forEach(stat -> responseTimeList.add(stat.getResponseTime()));
                List<Long> sortedList = responseTimeList.stream()
                                                        .sorted(Comparator.comparingLong(value -> value))
                                                        .collect(Collectors.toList());
                int tp90Indicator = (int) (statQueue.getLast()
                                                    .getMethodCallCount() * ALARM_90_PERCENT);
                int tp90Index = tp90Indicator > sortedList.size() - 1 ? sortedList.size() - 1 : tp90Indicator;
                System.out.println(Thread.currentThread()
                                         .getName() + "============" + entry.getKey() + "方法的TP90为：" + sortedList.get(tp90Index));
                int tp99Indicator = (int) (statQueue.getLast()
                                                    .getMethodCallCount() * ALARM_99_PERCENT);
                int tp99Index = tp99Indicator > sortedList.size() - 1 ? sortedList.size() - 1 : tp99Indicator;
                System.out.println(Thread.currentThread()
                                         .getName() + "============" + entry.getKey() + "方法的TP99为：" + sortedList.get(tp99Index));
            }
            ;
        }, 1, 5, TimeUnit.SECONDS);
        if (future.isDone()) {
            System.out.println("=================执行完毕");
        }

    }


//    @Override
//    public void run() {
////        long now = System.currentTimeMillis();
//        Map<String, LinkedList<Stat>> queueMap = Collections.unmodifiableMap(TPMonitorFilter.PERFORMANCE_MAP);
//        System.out.println(Thread.currentThread()
//                                 .getName() + "请求数据大小:" + queueMap.values()
//                                                                  .stream()
//                                                                  .flatMap(stat -> stat.stream())
//                                                                  .collect(Collectors.toList())
//                                                                  .size() + ">>>>>>>>>>打印接口性能数据" + queueMap);
//
////        for (Map.Entry<String, Integer> callEntry : TPMonitorFilter.METHOD_CALL.entrySet()) {
////            String methodName1 = callEntry.getKey();
////            for (Map.Entry<String, Map<Long, Long>> rtEntry : TPMonitorFilter.METHOD_RESPONSE_TIME.entrySet()) {
////                String methodName2 = rtEntry.getKey();
////                if (StringUtils.equals(methodName1, methodName2)) {
////                    List<Long> latestCallList = rtEntry.getValue()
////                                                       .keySet()
////                                                       .parallelStream()
////                                                       .filter(key -> now - key <= 1 * 60 * 1000)
////                                                       .collect(Collectors.toList());
////                    List<Long> responseTimeList = Lists.newLinkedList();
////                    for (Map.Entry<Long, Long> entry : rtEntry.getValue()
////                                                              .entrySet()) {
////                        if (latestCallList.contains(entry.getKey())) {
////                            responseTimeList.add(entry.getValue());
////                        }
////                    }
////                    List<Long> sortedList = responseTimeList.stream()
////                                                            .sorted(Comparator.comparingLong(value -> value))
////                                                            .collect(Collectors.toList());
////                    int tp90Indicator = (int) (callEntry.getValue() * ALARM_90_PERCENT);
////                    System.out.println(callEntry.getKey() + "方法的TP90为：" + sortedList.get(tp90Indicator));
////                    int tp99Indicator = (int) (callEntry.getValue() * ALARM_99_PERCENT);
////                    System.out.println(callEntry.getKey() + "方法的TP99为：" + sortedList.get(tp99Indicator));
////                    break;
////                }
////            }
////        }
//        queueMap.entrySet().parallelStream().forEach(entry->{
//            //            String methodName = entry.getKey();
//            LinkedList<Stat> statQueue = entry.getValue();
////            Stat[] stats = statQueue.toArray(new Stat[statQueue.size()]);
////            List<Long> latestCallList = rtEntry.getValue()
////                                               .keySet()
////                                               .parallelStream()
////                                               .filter(key -> now - key <= 1 * 60 * 1000)
////                                               .collect(Collectors.toList());
//            List<Long> responseTimeList = Lists.newLinkedList();
//            statQueue.forEach(stat -> responseTimeList.add(stat.getResponseTime()));
////            for (Map.Entry<Long, Long> entry : rtEntry.getValue()
////                                                      .entrySet()) {
////                if (latestCallList.contains(entry.getKey())) {
////                    responseTimeList.add(entry.getValue());
////                }
////            }
//            List<Long> sortedList = responseTimeList.stream()
//                                                    .sorted(Comparator.comparingLong(value -> value))
//                                                    .collect(Collectors.toList());
//            int tp90Indicator = (int) (statQueue.getLast()
//                                                .getMethodCallCount() * ALARM_90_PERCENT);
//            System.out.println(entry.getKey() + "方法的TP90为：" + sortedList.get(tp90Indicator));
//            int tp99Indicator = (int) (statQueue.getLast()
//                                                .getMethodCallCount() * ALARM_99_PERCENT);
//            System.out.println(entry.getKey() + "方法的TP99为：" + sortedList.get(tp99Indicator));
//        });
////        for (Map.Entry<String, LinkedList<Stat>> entry : queueMap.entrySet()) {
//////            String methodName = entry.getKey();
////            LinkedList<Stat> statQueue = entry.getValue();
//////            Stat[] stats = statQueue.toArray(new Stat[statQueue.size()]);
//////            List<Long> latestCallList = rtEntry.getValue()
//////                                               .keySet()
//////                                               .parallelStream()
//////                                               .filter(key -> now - key <= 1 * 60 * 1000)
//////                                               .collect(Collectors.toList());
////            List<Long> responseTimeList = Lists.newLinkedList();
////            statQueue.forEach(stat -> responseTimeList.add(stat.getResponseTime()));
//////            for (Map.Entry<Long, Long> entry : rtEntry.getValue()
//////                                                      .entrySet()) {
//////                if (latestCallList.contains(entry.getKey())) {
//////                    responseTimeList.add(entry.getValue());
//////                }
//////            }
////            List<Long> sortedList = responseTimeList.stream()
////                                                    .sorted(Comparator.comparingLong(value -> value))
////                                                    .collect(Collectors.toList());
////            int tp90Indicator = (int) (statQueue.getLast()
////                                                .getMethodCallCount() * ALARM_90_PERCENT);
////            System.out.println(entry.getKey() + "方法的TP90为：" + sortedList.get(tp90Indicator));
////            int tp99Indicator = (int) (statQueue.getLast()
////                                                .getMethodCallCount() * ALARM_99_PERCENT);
////            System.out.println(entry.getKey() + "方法的TP99为：" + sortedList.get(tp99Indicator));
////        }
//    }
}
